package com.sgdh.quote.server;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.PostConstruct;

import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.sgdh.quote.constant.Terminal;
import com.sgdh.quote.server.handler.ServerHandler;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class Server {
    @Autowired
    private ServerHandler serverHandler;

    @Autowired
    private Terminal terminal;

    @PostConstruct
    public void start() {
        //定义接受及处理线程组
        final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        final EventLoopGroup workerGroup = new NioEventLoopGroup();
        //当程序关闭时，关闭钩子中的代码会被执行，从而实现了优雅地关闭相关线程池的功能
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public synchronized void start() {
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
            }
        });
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            //绑定线程组并指定NIO模型为NIOServer，使用ChannelInitializer来初始化SocketChannel，
            //设置了一个ChannelPipeline，并在其中添加了ImageEncoder、LineBasedFrameDecoder、StringDecoder和serverHandler这些处理器
            bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            //增加出栈数据处理类
                            pipeline.addLast(new ImageEncoder())
                                    //在管道中添加一个按行划分帧的解码器。这个解码器用于将数据按行划分。
                                    .addLast(new LineBasedFrameDecoder(1024))
                                    //设置字符集
                                    .addLast(new StringDecoder(CharsetUtil.UTF_8))
                                    //设置入栈数据处理类
                                    .addLast(serverHandler);
                        }
                    }).option(ChannelOption.SO_BACKLOG, 102400);
            ChannelFuture future = bootstrap.bind(terminal.getPort());
            log.info("开启{}端口监听", terminal.getPort());
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
